﻿using LK.WebAPI.appsettings;
using LK.WebAPI.LK.WebAPI.ApiResult;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace LK.WebAPI
{
    public class LogAttribute : ActionFilterAttribute
    {
        private AppSettings _appSetting { get; }
        public LogAttribute(IOptions<AppSettings> appSetting)
        {
            
            _appSetting = appSetting.Value;
            RequestId = GenerateId();
            this.CreateTime = DateTime.Now;
        }
        public string IP { get; set; }
        public string RequestId;
        public string ActionArguments;
        public string RequestBody;
        public string RequestUrl;
        public string RequestMethod;
        public string qs;
        public string ResposeBody;
        public Exception ex;
        public DateTime CreateTime;
        public Stopwatch Stopwatch;

        #region 重写方法
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine("OnActionExecuting");
            base.OnActionExecuting(context);

            // 后续添加了获取请求的请求体，如果在实际项目中不需要删除即可
            long contentLen = context.HttpContext.Request.ContentLength == null ? 0 : context.HttpContext.Request.ContentLength.Value;
            if (contentLen > 0)
            {
                // 读取请求体中所有内容
                System.IO.Stream stream = context.HttpContext.Request.Body;
                if (context.HttpContext.Request.Method.ToUpper() == "POST")
                {
                    stream.Position = 0;
                }
                byte[] buffer = new byte[contentLen];
                stream.Read(buffer, 0, buffer.Length);
                // 转化为字符串
                RequestBody = System.Text.Encoding.UTF8.GetString(buffer);
            }

            ActionArguments = JsonConvert.SerializeObject(context.ActionArguments);

            Stopwatch = new Stopwatch();
            Stopwatch.Start();
        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine("OnActionExecuted");

            //请求正常结束,否则直接在异常捕获
            base.OnActionExecuted(context);
            Stopwatch.Stop();

            RequestUrl = context.HttpContext.Request.Host + context.HttpContext.Request.Path + context.HttpContext.Request.QueryString;
            RequestMethod = context.HttpContext.Request.Method;
            qs = ActionArguments;

            if (context.Result is ResposeStatus)
            {
                var res = context.Result as ResposeStatus;
                res.RequestId = this.RequestId;
            }

        }
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            base.OnResultExecuted(context);
        }
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            base.OnResultExecuting(context);
        }

        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            return base.OnActionExecutionAsync(context, next);
        } 
        #endregion

        #region 私有方法
        private string GenerateId()
        {
            string id = DateTime.Now.ToString("yyMMddHHmmssffff") + new Random().Next(0, 1000);
            return id;
        } 
        #endregion

        #region 公用方法
        public string PrintLog()
        {
            string log = ($"地址：{RequestUrl} \n " +
                          $"方式：{RequestMethod} \n " +
                          $"请求体：{RequestBody} \n " +
                          $"参数：{qs}\n " +
                          $"结果：{ResposeBody}\n " +
                          $"耗时：{Stopwatch.Elapsed.TotalMilliseconds} 毫秒（指控制器内对应方法执行完毕的时间）");
            return log;
        }
        /// <summary>
        /// 写入日志队列
        /// </summary>
        public void Push()
        {

        } 
        #endregion
    }
}
